/**
 * Title:		KFrogMain.java
 * Description: This is the main class. Interpretation begins here. 
 * 
 * @version		1.0 May 2009
 * @author		Rami Habas
 */

package kfrog;

import antlr.debug.misc.ASTFrame;
import java.io.*;

public class KFrogMain {
	
	/** command line arguments supplied by the user */
	public  static boolean debug;
	public  static boolean test;
	public  static boolean testSyntax;
	public  static boolean testSemantics;
	private static boolean help;
	private static String  filename;

	/**
     * Main function that runs the interpreter.
     * 
     * @param args   User supplied arguments
     */
	public static void main(String[] args) {
		KFrogAntlrLexer lexer;
		KFrogAntlrParser parser;
		KFrogAST tree;
		KFrogAntlrWalker walker = null;
		init();

		try {
			getArgs(args);
		}
		catch (Exception e) {
			System.out.flush();
			String message = "Error: " + e.getMessage();
			System.err.println(message);
			if (debug)
				e.printStackTrace();
			System.exit(1);
		}

		if (help) {
			printHelp();
			System.exit(0);
		}

		try {
			lexer = new KFrogAntlrLexer(new FileReader(filename));
			lexer.setFilename(filename);

			parser = new KFrogAntlrParser(lexer);
			parser.setFilename(filename);
			parser.setASTNodeClass(KFrogAST.class.getName());
			parser.program();
			tree = (KFrogAST)parser.getAST();
			if (debug) {
				ASTFrame frame = new ASTFrame("Tree", tree);
				frame.setVisible(true);
			}
			if(testSyntax || test || debug){
				System.out.println("Tree:" + tree.toStringList());
				System.out.println();
			}
			if(!testSyntax){
				walker = new KFrogAntlrWalker();
				walker.extern_def(tree);
				walker.main_func(tree);
			}
		} catch (Exception e) {
			System.out.flush();
			String message = "Error: " + e.getMessage();
			System.err.println(message);
			if (debug)
				e.printStackTrace();
		}
	}

	/** initialize the command line arguments to default values */
	private static void init() {
		debug = test = testSyntax = testSemantics = help = false;
		filename = null;
	}

	/**
     * Parses the command line arguments supplied by the user.
     * 
     * @param args   User supplied arguments
     */
	private static void getArgs(String[] args) {
		for (int i = 0; i < args.length; i++) {
			if (args[i].equals("--help")) {
				help = true;
				return;
			}

			if (args[i].equals("--test-syntax")) {
				testSyntax = true;
			}
			else if (args[i].equals("--test-semantics")) {
				testSemantics = true;
			}
			else if (args[i].equals("--test")) {
				test = true;
			}
			else if (args[i].equals("--debug")) {
				debug = true;
			}
			else {
				if (null != filename)
					throw new IllegalArgumentException("Illegal argument: " +
							args[i]);
				filename = args[i];
			}
		}
		if (test || testSemantics || testSyntax)
			debug = false;
	}

	private static void printHelp() {
		System.out.println("NAME");
		System.out.println("        " + KFrogMain.class.getName() 
				+ " - interpret KFrog source file");
		System.out.println();
		System.out.println("SYNOPSIS");
		System.out.println("        java " + KFrogMain.class.getName()
				+ " [OPTION]... FILE");
		System.out.println();
		System.out.println("DESCRIPTION");
		System.out.println("        Interprets the given KFrog FILE.");
		System.out.println();
		System.out.println("OPTIONS");
		System.out.println("        --test");
		System.out.println("                for complete testing purposes");
		System.out.println();
		System.out.println("        --test-syntax");
		System.out.println("                for testing syntax only");
		System.out.println();
		System.out.println("        --test-semantics");
		System.out.println("                for testing semantics only");
		System.out.println();
		System.out.println("        --debug");
		System.out.println("                show debugging information");
		System.out.println();
		System.out.println("        --help");
		System.out.println("                show this message");
		System.out.println();
		System.out.println("FILE");
		System.out.println("        Specifies the file to be interpreted.");
	}
}